﻿using AMAP.Areas.Admin.Models.Account;
using AMAP.Areas.Client.Models.Account;
using AMAP.Areas.Supplier.Models.Account;
using AMAP.ServiceClasses;
using AMAP.ServiceClasses.Common;
using AMAP.ServiceInterfaces;
using AMAP.ServiceInterfaces.Common;
using Autofac;
using Autofac.Integration.Mvc;
using AutoMapper;
using System.Web.Mvc;
using System.Web.Routing;

namespace AMAP
{
    // Note: For instructions on enabling IIS6 or IIS7 classic mode, 
    // visit http://go.microsoft.com/?LinkId=9394801

    public class MvcApplication : System.Web.HttpApplication
    {
        public static void RegisterGlobalFilters(GlobalFilterCollection filters)
        {
            filters.Add(new HandleErrorAttribute());
        }

        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            routes.MapRoute(
                "Default", // Route name
                "{controller}/{action}/{id}", // URL with parameters
                new { controller = "Home", action = "Index", id = UrlParameter.Optional }, // Parameter defaults
                new string[] { typeof(AMAP.Areas.Public.Controllers.HomeController).Namespace }
            ).DataTokens.Add("area", "Public");

        }

        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();

            //Double validation for French culture (4,01 instead of 4.01)
            ModelBinders.Binders.Add(typeof(decimal), new DecimalModelBinder());


            RegisterGlobalFilters(GlobalFilters.Filters);
            RegisterRoutes(RouteTable.Routes);

            InitAutofac();
            InitAutoMapper();
        }

        private static void InitAutofac()
        {
            // Begin of dependency injection with Autofac
            var builder = new ContainerBuilder();
            // Start of application specific code for DI
            builder.Register(s => new DatabaseFactory()).As<IDatabaseFactory>().InstancePerHttpRequest();

            builder.Register(s => new AmapService(DependencyResolver.Current.GetService<IDatabaseFactory>())).As<IAmapService>().InstancePerHttpRequest();
            builder.Register(s => new AuthenticationService(DependencyResolver.Current.GetService<IDatabaseFactory>())).As<IAuthenticationService>().InstancePerHttpRequest();
            builder.Register(s => new BasketOrderService(DependencyResolver.Current.GetService<IDatabaseFactory>())).As<IBasketOrderService>().InstancePerHttpRequest();
            builder.Register(s => new BasketService(DependencyResolver.Current.GetService<IDatabaseFactory>())).As<IBasketService>().InstancePerHttpRequest();
            builder.Register(s => new ClientService(DependencyResolver.Current.GetService<IDatabaseFactory>())).As<IClientService>().InstancePerHttpRequest();
            builder.Register(s => new CompositionService(DependencyResolver.Current.GetService<IDatabaseFactory>())).As<ICompositionService>().InstancePerHttpRequest();
            builder.Register(s => new CoordinatesService(DependencyResolver.Current.GetService<IDatabaseFactory>())).As<ICoordinatesService>().InstancePerHttpRequest();
            builder.Register(s => new DeliveryService(DependencyResolver.Current.GetService<IDatabaseFactory>())).As<IDeliveryService>().InstancePerHttpRequest();
            builder.Register(s => new ExternalCompositionService(DependencyResolver.Current.GetService<IDatabaseFactory>())).As<IExternalCompositionService>().InstancePerHttpRequest();
            builder.Register(s => new ExternalOrderService(DependencyResolver.Current.GetService<IDatabaseFactory>())).As<IExternalOrderService>().InstancePerHttpRequest();
            builder.Register(s => new OfferService(DependencyResolver.Current.GetService<IDatabaseFactory>())).As<IOfferService>().InstancePerHttpRequest();
            builder.Register(s => new OrderService(DependencyResolver.Current.GetService<IDatabaseFactory>())).As<IOrderService>().InstancePerHttpRequest();
            builder.Register(s => new OtherAmapService(DependencyResolver.Current.GetService<IDatabaseFactory>())).As<IOtherAmapService>().InstancePerHttpRequest();
            builder.Register(s => new ProductService(DependencyResolver.Current.GetService<IDatabaseFactory>())).As<IProductService>().InstancePerHttpRequest();
            builder.Register(s => new PlaceService(DependencyResolver.Current.GetService<IDatabaseFactory>())).As<IPlaceService>().InstancePerHttpRequest();
            builder.Register(s => new ProductService(DependencyResolver.Current.GetService<IDatabaseFactory>())).As<IProductService>().InstancePerHttpRequest();
            builder.Register(s => new QuarterService(DependencyResolver.Current.GetService<IDatabaseFactory>())).As<IQuarterService>().InstancePerHttpRequest();
            builder.Register(s => new RequestService(DependencyResolver.Current.GetService<IDatabaseFactory>())).As<IRequestService>().InstancePerHttpRequest();
            builder.Register(s => new RoleService(DependencyResolver.Current.GetService<IDatabaseFactory>())).As<IRoleService>().InstancePerHttpRequest();
            builder.Register(s => new SubscriptionService(DependencyResolver.Current.GetService<IDatabaseFactory>())).As<ISubscriptionService>().InstancePerHttpRequest();
            builder.Register(s => new SupplierService(DependencyResolver.Current.GetService<IDatabaseFactory>())).As<ISupplierService>().InstancePerHttpRequest();
            builder.Register(s => new UserService(DependencyResolver.Current.GetService<IDatabaseFactory>())).As<IUserService>().InstancePerHttpRequest();
            builder.Register(s => new VolunteerRoleService(DependencyResolver.Current.GetService<IDatabaseFactory>())).As<IVolunteerRoleService>().InstancePerHttpRequest();
            builder.Register(s => new VolunteerService(DependencyResolver.Current.GetService<IDatabaseFactory>())).As<IVolunteerService>().InstancePerHttpRequest();


            // ...
            // To complete as dependency are created
            // ...
            // End of application specific code for DI
            builder.RegisterControllers(typeof(MvcApplication).Assembly);
            var container = builder.Build();
            DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
            // End of dependency injection with autofac
        }

        private static void InitAutoMapper()
        {
            //---------------------------------ViewModel to POCO
            // Map Client account creation
            Mapper.CreateMap<ClientAccountCreateViewModel, Domain.User>();
            Mapper.CreateMap<ClientAccountCreateViewModel, Domain.Client>();

            Mapper.CreateMap<ClientAccountAddCoordinatesViewModel, Domain.Coordinates>();

            // Map Supplier account creation
            Mapper.CreateMap<SupplierAccountCreateViewModel, Domain.User>();
            Mapper.CreateMap<SupplierAccountCreateViewModel, Domain.Supplier>();
            Mapper.CreateMap<SupplierAccountCreateViewModel, Domain.Coordinates>();

            //Map Admin account creation
            Mapper.CreateMap<AdminAccountCreateViewModel, Domain.User>();
            Mapper.CreateMap<AdminAccountCreateViewModel, Domain.Volunteer>();

            // Map Supplier account edition
            Mapper.CreateMap<Domain.Coordinates, SupplierAccountEditViewModel>();
            Mapper.CreateMap<Domain.User, SupplierAccountEditViewModel>();
            Mapper.CreateMap<Domain.Supplier, SupplierAccountEditViewModel>();

            // Map Client coordinates edition
            Mapper.CreateMap<AdminAccountAddCoordinatesViewModel, Domain.Coordinates>();


            //---------------------------------POCO to ViewModel
            Mapper.CreateMap<Domain.Coordinates, AdminAccountEditCoordinatesViewModel>();
            Mapper.CreateMap<Domain.Coordinates, ClientAccountEditCoordinatesViewModel>();




        }
    }
}